import 'dart:io';

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:nyh_motorcade_app/config/config.dart';
import 'package:nyh_motorcade_app/routes/routes.dart';
import 'package:nyh_motorcade_app/utils/toast_utils.dart';
import 'package:nyh_motorcade_app/widgets/loading_dialog.dart';
import 'package:nyh_motorcade_app/widgets/multi_state/multi_state_widget.dart';
import 'interceptors/header_interceptor.dart';
import 'interceptors/logger_interceptor.dart';
import 'interceptors/error_interceptor.dart';

typedef SuccessCallback = void Function(dynamic data);
typedef FailCallback = void Function(int code, String msg);
typedef ErrorCallback = void Function(String msg);

final HttpManager httpManager = HttpManager();

class HttpManager {
  Dio _dio = Dio(
    BaseOptions(
      baseUrl: Config.baseUrl,
      method: Config.defaultMethod,
      connectTimeout: Config.connectTimeout,
      receiveTimeout: Config.receiveTimeout,
    ),
  )
    ..interceptors.add(HeaderInterceptors())
    ..interceptors.add(ErrorInterceptor())
    ..interceptors.add(LoggerInterceptors());

  // HttpManager() {
  //   //设置代理(给测试用)
  //   if (Config.debug) {
  //     (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
  //       //这一段是解决安卓https抓包的问题
  //       client.badCertificateCallback = (X509Certificate cert, String host, int port) {
  //         return Platform.isAndroid;
  //       };
  //       client.findProxy = (uri) {
  //         return "PROXY 192.168.0.9:9999";
  //       };
  //     };
  //   }
  // }

  void setBaseUrl(String baseUrl) {
    _dio.options.baseUrl = baseUrl;
  }

  Future<HttpResult> post(
    BuildContext? context,
    String path,
    dynamic params, {
    Map<String, dynamic>? headers,
    bool isToast = false,
    bool isLoadingDialog = false,
    SuccessCallback? onSuccess,
    FailCallback? onFail,
    ErrorCallback? onError,
  }) async {
    try {
      showLoadingDialog(context, isLoadingDialog);
      if (headers != null) {
        _dio.options.headers.addAll(headers);
      }
      Response response = await _dio.post(path, data: params);
      if (response.statusCode == 200) {
        int code = response.data["status"]["code"];
        if (code == 0) {
          dynamic data = response.data["data"];
          dismissLoadingDialog(context, isLoadingDialog);
          if (onSuccess != null) {
            onSuccess(data);
          }
          return HttpResult(data: data, state: MultiState.success);
        } else if (code == 401) {
          //token过期
          showToast(isToast, response.data["status"]["msg"]);
          dismissLoadingDialog(context, isLoadingDialog);
          Routes.pushNamedAndRemoveUntil(Routes.login);
          return HttpResult();
        } else {
          String msg = response.data["status"]["msg"];
          showToast(isToast, msg);
          dismissLoadingDialog(context, isLoadingDialog);
          if (onFail != null) {
            onFail(code, msg);
          }
          return HttpResult(code: code, msg: msg, state: MultiState.fail);
        }
      } else {
        String msg = "未知异常";
        showToast(isToast, msg);
        dismissLoadingDialog(context, isLoadingDialog);
        if (onError != null) {
          onError(msg);
        }
        return HttpResult(msg: msg, state: MultiState.error);
      }
    } on DioError catch (e) {
      String msg = e.type.errorMsg;
      showToast(isToast, msg);
      dismissLoadingDialog(context, isLoadingDialog);
      if (onError != null) {
        onError(msg);
      }
      return HttpResult(msg: msg, state: MultiState.error);
    }
  }

  void download(
    BuildContext context,
    String path,
    String savePath, {
    bool isToast = false,
    bool isLoadingDialog = false,
    SuccessCallback? onSuccess,
    ErrorCallback? onError,
  }) async {
    try {
      showLoadingDialog(context, isLoadingDialog);
      Response response = await _dio.download(
        path,
        savePath,
        onReceiveProgress: (count, total) {
          // if (total != -1) {
          //   print("下载进度:" + (count / total * 100).toStringAsFixed(0) + "%");
          // }
        },
      );
      if (response.statusCode == 200) {
        dismissLoadingDialog(context, isLoadingDialog);
        if (onSuccess != null) {
          onSuccess(response.data);
        }
      } else {
        showToast(isToast, "未知异常");
        dismissLoadingDialog(context, isLoadingDialog);
        if (onError != null) {
          onError("未知异常");
        }
      }
    } on DioError catch (e) {
      String msg = e.type.errorMsg;
      showToast(isToast, msg);
      dismissLoadingDialog(context, isLoadingDialog);
      if (onError != null) {
        onError(msg);
      }
    }
  }
}

void showLoadingDialog(BuildContext? context, bool isLoadingDialog) {
  if (context != null && isLoadingDialog) {
    LoadingDialog.showCustomDialog(context);
  }
}

void showToast(bool isToast, String msg) {
  if (isToast) {
    ToastUtils.toast(msg);
  }
}

void dismissLoadingDialog(BuildContext? context, bool isLoadingDialog) {
  if (context != null && isLoadingDialog) {
    LoadingDialog.dismissDialog(context);
  }
}

extension ConvertExtension on DioErrorType {
  String get errorMsg {
    switch (this) {
      case DioErrorType.connectTimeout:
      case DioErrorType.sendTimeout:
      case DioErrorType.receiveTimeout:
        return "连接超时";
      case DioErrorType.response:
        return "服务器异常";
      case DioErrorType.cancel:
        return "请求取消";
      case DioErrorType.other:
        return "其他异常";
      default:
        return "未知异常";
    }
  }
}

class HttpResult {
  dynamic data;
  int? code;
  String? msg;
  MultiState? state;

  HttpResult({this.data, this.code, this.msg, this.state});
}
